/******************************************************************************* * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Francis Upton - <francisu@ieee.org> - * Fix for Bug 217777 [Workbench] Workbench event loop does not terminate if Display is closed * Tasktop Technologies - Bug 304716 - [UX] [Progress] Show Eclipse startup progress in the Eclipse icon on the Windows 7 Task Bar * Tom Schindl - Bug 310153 - Allow people to use CSS in 3.x plugins * EclipseSource - adaptation for RAP *******************************************************************************/ package org.eclipse.ui.internal; import java.io.IOException; import java.io.StringReader; import java.io.StringWriter; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.core.commands.Command; import org.eclipse.core.commands.CommandManager; import org.eclipse.core.commands.common.EventManager; import org.eclipse.core.commands.contexts.ContextManager; import org.eclipse.core.databinding.observable.Realm; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionDelta; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IRegistryChangeEvent; import org.eclipse.core.runtime.IRegistryChangeListener; import org.eclipse.core.runtime.ISafeRunnable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.ListenerList; import org.eclipse.core.runtime.MultiStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.ExternalActionManager; import org.eclipse.jface.action.ExternalActionManager.CommandCallback; import org.eclipse.jface.action.ExternalActionManager.IActiveChecker; import org.eclipse.jface.action.ExternalActionManager.IExecuteApplicable; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.bindings.BindingManager; import org.eclipse.jface.bindings.BindingManagerEvent; import org.eclipse.jface.bindings.IBindingManagerListener; import org.eclipse.jface.databinding.swt.SWTObservables; import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.ModalContext; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceManager; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.util.OpenStrategy; import org.eclipse.jface.util.SafeRunnable; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.window.IShellProvider; import org.eclipse.jface.window.Window; import org.eclipse.jface.window.WindowManager; import org.eclipse.osgi.util.NLS; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.SingletonUtil; import org.eclipse.rap.rwt.service.SettingStore; import org.eclipse.rap.ui.internal.branding.BrandingUtil; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.BusyIndicator; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IDecoratorManager; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorRegistry; import org.eclipse.ui.IElementFactory; import org.eclipse.ui.ILocalWorkingSetManager; import org.eclipse.ui.IMemento; import org.eclipse.ui.IPerspectiveDescriptor; import org.eclipse.ui.IPerspectiveRegistry; import org.eclipse.ui.ISaveableFilter; import org.eclipse.ui.ISaveablePart; import org.eclipse.ui.ISaveablesLifecycleListener; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.ISourceProvider; import org.eclipse.ui.ISources; import org.eclipse.ui.IWindowListener; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchListener; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPreferenceConstants; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkingSetManager; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.Saveable; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.XMLMemento; import org.eclipse.ui.activities.IWorkbenchActivitySupport; import org.eclipse.ui.application.IWorkbenchConfigurer; import org.eclipse.ui.application.WorkbenchAdvisor; import org.eclipse.ui.browser.IWorkbenchBrowserSupport; import org.eclipse.ui.commands.ICommandImageService; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.contexts.IWorkbenchContextSupport; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.help.IWorkbenchHelpSystem; import org.eclipse.ui.internal.StartupThreading.StartupRunnable; import org.eclipse.ui.internal.actions.CommandAction; import org.eclipse.ui.internal.activities.ws.WorkbenchActivitySupport; import org.eclipse.ui.internal.browser.WorkbenchBrowserSupport; import org.eclipse.ui.internal.commands.CommandImageManager; import org.eclipse.ui.internal.commands.CommandImageService; import org.eclipse.ui.internal.commands.CommandService; import org.eclipse.ui.internal.contexts.ActiveContextSourceProvider; import org.eclipse.ui.internal.contexts.ContextService; import org.eclipse.ui.internal.contexts.WorkbenchContextSupport; import org.eclipse.ui.internal.dialogs.PropertyPageContributorManager; import org.eclipse.ui.internal.help.WorkbenchHelpSystem; import org.eclipse.ui.internal.intro.IIntroRegistry; import org.eclipse.ui.internal.intro.IntroDescriptor; import org.eclipse.ui.internal.keys.BindingService; import org.eclipse.ui.internal.menus.FocusControlSourceProvider; import org.eclipse.ui.internal.menus.WorkbenchMenuService; import org.eclipse.ui.internal.misc.Policy; import org.eclipse.ui.internal.misc.StatusUtil; import org.eclipse.ui.internal.misc.UIStats; import org.eclipse.ui.internal.model.ContributionService; import org.eclipse.ui.internal.progress.ProgressManager; import org.eclipse.ui.internal.progress.ProgressManagerUtil; import org.eclipse.ui.internal.registry.IActionSetDescriptor; import org.eclipse.ui.internal.registry.IWorkbenchRegistryConstants; import org.eclipse.ui.internal.registry.UIExtensionTracker; import org.eclipse.ui.internal.services.ActionSetSourceProvider; import org.eclipse.ui.internal.services.EvaluationService; import org.eclipse.ui.internal.services.IServiceLocatorCreator; import org.eclipse.ui.internal.services.IWorkbenchLocationService; import org.eclipse.ui.internal.services.MenuSourceProvider; import org.eclipse.ui.internal.services.ServiceLocator; import org.eclipse.ui.internal.services.ServiceLocatorCreator; import org.eclipse.ui.internal.services.SourceProviderService; import org.eclipse.ui.internal.services.WorkbenchLocationService; import org.eclipse.ui.internal.testing.ContributionInfoMessages; import org.eclipse.ui.internal.testing.WorkbenchTestable; import org.eclipse.ui.internal.themes.ColorDefinition; import org.eclipse.ui.internal.themes.FontDefinition; import org.eclipse.ui.internal.themes.ThemeElementHelper; import org.eclipse.ui.internal.themes.WorkbenchThemeManager; import org.eclipse.ui.internal.tweaklets.GrabFocus; import org.eclipse.ui.internal.tweaklets.Tweaklets; import org.eclipse.ui.internal.tweaklets.WorkbenchImplementation; import org.eclipse.ui.internal.util.BundleUtility; import org.eclipse.ui.internal.util.PrefUtil; import org.eclipse.ui.internal.util.Util; import org.eclipse.ui.intro.IIntroManager; import org.eclipse.ui.keys.IBindingService; import org.eclipse.ui.menus.IMenuService; import org.eclipse.ui.model.IContributionService; import org.eclipse.ui.operations.IWorkbenchOperationSupport; import org.eclipse.ui.progress.IProgressService; import org.eclipse.ui.services.IDisposable; import org.eclipse.ui.services.IEvaluationService; import org.eclipse.ui.services.IServiceScopes; import org.eclipse.ui.services.ISourceProviderService; import org.eclipse.ui.statushandlers.StatusManager; import org.eclipse.ui.swt.IFocusService; import org.eclipse.ui.testing.ContributionInfo; import org.eclipse.ui.themes.IThemeManager; import org.eclipse.ui.views.IViewRegistry; import org.eclipse.ui.wizards.IWizardRegistry; import org.osgi.framework.Bundle; import org.osgi.framework.ServiceRegistration; import com.ibm.icu.util.ULocale; /** * The workbench class represents the top of the Eclipse user interface. Its * primary responsability is the management of workbench windows, dialogs, * wizards, and other workbench-related windows. * <p> * Note that any code that is run during the creation of a workbench instance * should not required access to the display. * </p> * <p> * Note that this internal class changed significantly between 2.1 and 3.0. * Applications that used to define subclasses of this internal class need to be * rewritten to use the new workbench advisor API. * </p> */ public final class Workbench extends EventManager implements IWorkbench { // RAP [bm] no task bar // private final class TaskBarDelegatingProgressMontior implements IProgressMonitor { // private final Shell shell; // private IProgressMonitor progessMonitor; // private TaskItem systemTaskItem; // private int totalWork; // private int totalWorked; // // public TaskBarDelegatingProgressMontior(IProgressMonitor progressMonitor, Shell shell) { // Assert.isNotNull(progressMonitor); // this.shell = shell; // this.progessMonitor = progressMonitor; // } // // /* // * (non-Javadoc) // * // * @see // * org.eclipse.core.runtime.IProgressMonitor#beginTask(java.lang.String, // * int) // */ // public void beginTask(String name, int totalWork) { // progessMonitor.beginTask(name, totalWork); // if (this.totalWork == 0) { // this.totalWork = totalWork; // } // } // // /* // * (non-Javadoc) // * // * @see org.eclipse.core.runtime.IProgressMonitor#worked(int) // */ // public void worked(int work) { // progessMonitor.worked(work); // totalWorked += work; // if (Display.getCurrent() != null) { // handleTaskBarProgressUpdated(); // } else if (getDisplay() != null && !getDisplay().isDisposed()) { // getDisplay().asyncExec(new Runnable() { // public void run() { // handleTaskBarProgressUpdated(); // } // }); // } // } // // /* // * (non-Javadoc) // * // * @see org.eclipse.core.runtime.IProgressMonitor#done() // */ // public void done() { // progessMonitor.done(); // // if (Display.getCurrent() != null) { // handleTaskBarProgressDone(); // } else if (getDisplay() != null && !getDisplay().isDisposed()) { // getDisplay().asyncExec(new Runnable() { // public void run() { // handleTaskBarProgressDone(); // } // }); // } // } // // private TaskItem getTaskItem(Shell shell) { // if (Display.getCurrent() == null) { // return null; // } // if (systemTaskItem == null) { // if (getDisplay() != null && shell != null && !shell.isDisposed()) { // TaskBar systemTaskBar = getDisplay().getSystemTaskBar(); // if (systemTaskBar != null) { // systemTaskItem = systemTaskBar.getItem(shell); // if (systemTaskItem == null) { // // fall back to the application TaskItem if there // // isn't one for the shell // systemTaskItem = systemTaskBar.getItem(null); // } // } // } // } // return systemTaskItem; // } // // private void handleTaskBarProgressUpdated() { // if (systemTaskItem == null) { // systemTaskItem = getTaskItem(shell); // } // if (systemTaskItem != null && !systemTaskItem.isDisposed()) { // if (systemTaskItem.getProgressState() != SWT.NORMAL) { // systemTaskItem.setProgressState(SWT.NORMAL); // } // float percentComplete = ((float) totalWorked / (float) totalWork) * 100f; // systemTaskItem.setProgress(Math.round(percentComplete)); // } // } // // private void handleTaskBarProgressDone() { // if (systemTaskItem == null) { // systemTaskItem = getTaskItem(shell); // } // if (systemTaskItem != null && !systemTaskItem.isDisposed()) { // if (systemTaskItem.getProgressState() != SWT.DEFAULT) { // systemTaskItem.setProgressState(SWT.DEFAULT); // } // } // } // // /* // * (non-Javadoc) // * // * @see org.eclipse.core.runtime.IProgressMonitor#internalWorked(double) // */ // public void internalWorked(double work) { // progessMonitor.internalWorked(work); // } // // /* // * (non-Javadoc) // * // * @see org.eclipse.core.runtime.IProgressMonitor#isCanceled() // */ // public boolean isCanceled() { // return progessMonitor.isCanceled(); // } // // /* // * (non-Javadoc) // * // * @see org.eclipse.core.runtime.IProgressMonitor#setCanceled(boolean) // */ // public void setCanceled(boolean value) { // progessMonitor.setCanceled(value); // } // // /* // * (non-Javadoc) // * // * @see // * org.eclipse.core.runtime.IProgressMonitor#setTaskName(java.lang.String // * ) // */ // public void setTaskName(String name) { // progessMonitor.setTaskName(name); // } // // /* // * (non-Javadoc) // * // * @see // * org.eclipse.core.runtime.IProgressMonitor#subTask(java.lang.String) // */ // public void subTask(String name) { // progessMonitor.subTask(name); // } // // } // RAP [fappel]: key for storing workbench state into setting store private static final String KEY_WORKBENCH_STATE = Workbench.class.getName() + "#XMLMemento"; // RAP [fappel]: ensure that workbench is properly shutdown in case of session timeout /** * */ private boolean started; private boolean sessionInvalidated; private static final class ShutdownHandler implements Listener { public void handleEvent( Event event ){ if( Workbench.getInstance().started && Platform.isRunning() ) { Workbench.getInstance().sessionInvalidated = true; Workbench.getInstance().close(); } } } // RAPEND: [bm] // RAP [bm]: // private final class StartupProgressBundleListener implements // SynchronousBundleListener { // // private final IProgressMonitor progressMonitor; // // private final int maximumProgressCount; // // // stack of names of bundles currently starting // private final List starting; // // StartupProgressBundleListener(IProgressMonitor progressMonitor, // int maximumProgressCount) { // super(); // this.progressMonitor = progressMonitor; // this.maximumProgressCount = maximumProgressCount; // this.starting = new ArrayList(); // } // // public void bundleChanged(BundleEvent event) { // int eventType = event.getType(); // String bundleName; // // synchronized (this) { // if (eventType == BundleEvent.STARTING) { // starting.add(bundleName = event.getBundle() // .getSymbolicName()); // } else if (eventType == BundleEvent.STARTED) { // progressCount++; // if (progressCount <= maximumProgressCount) { // progressMonitor.worked(1); // } // int index = starting.lastIndexOf(event.getBundle() // .getSymbolicName()); // if (index >= 0) { // starting.remove(index); // } // if (index != starting.size()) { // return; // not currently displayed // } // bundleName = index == 0 ? null : (String) starting // .get(index - 1); // } else { // return; // uninteresting event // } // } // // String taskName; // // if (bundleName == null) { // taskName = WorkbenchMessages.Startup_Loading_Workbench; // } else { // taskName = NLS.bind(WorkbenchMessages.Startup_Loading, // bundleName); // } // // progressMonitor.subTask(taskName); // } // } // RAPEND: [bm] /** * Family for the early startup job. */ public static final String EARLY_STARTUP_FAMILY = "earlyStartup"; //$NON-NLS-1$ static final String VERSION_STRING[] = { "0.046", "2.0" }; //$NON-NLS-1$ //$NON-NLS-2$ static final String DEFAULT_WORKBENCH_STATE_FILENAME = "workbench.xml"; //$NON-NLS-1$ // RAP [bm]: instance per session, see getInstance() // /** // * Holds onto the only instance of Workbench. // */ // private static Workbench instance; // RAPEND: [bm] /** * The testable object facade. */ // RAP [bm]: // private static WorkbenchTestable testableObject; private WorkbenchTestable testableObject; // RAPEND: [bm] // RAP [bm]: no splash today // /** // * Signals that the workbench should create a splash implementation when // * instantiated. Intial value is <code>true</code>. // */ // private static boolean createSplash = true; // // /** // * The splash handler. // */ // private static AbstractSplashHandler splash; // RAPEND: [bm] /** * The display used for all UI interactions with this workbench. */ private Display display; private WindowManager windowManager; private WorkbenchWindow activatedWindow; private EditorHistory editorHistory; private boolean runEventLoop = true; private boolean isStarting = true; private boolean isClosing = false; /** * PlatformUI return code (as opposed to IPlatformRunnable return code). */ private int returnCode = PlatformUI.RETURN_UNSTARTABLE; /** * Advisor providing application-specific configuration and customization of * the workbench. */ private WorkbenchAdvisor advisor; /** * Object for configuring the workbench. Lazily initialized to an instance * unique to the workbench instance. */ private WorkbenchConfigurer workbenchConfigurer; // for dynamic UI /** * ExtensionEventHandler handles extension life-cycle events. */ private ExtensionEventHandler extensionEventHandler; /** * A count of how many large updates are going on. This tracks nesting of * requests to disable services during a large update -- similar to the * <code>setRedraw</code> functionality on <code>Control</code>. When * this value becomes greater than zero, services are disabled. When this * value becomes zero, services are enabled. Please see * <code>largeUpdateStart()</code> and <code>largeUpdateEnd()</code>. */ private int largeUpdates = 0; /** * The service locator maintained by the workbench. These services are * initialized during workbench during the <code>init</code> method. */ private final ServiceLocator serviceLocator; /** * A count of how many plug-ins were loaded while restoring the workbench * state. Initially -1 for unknown number. */ private int progressCount = -1; /** * A field to hold the workbench windows that have been restored. In the * event that not all windows have been restored, this field allows the * openWindowsAfterRestore method to open some windows. */ private WorkbenchWindow[] createdWindows; /** * Listener list for registered IWorkbenchListeners . */ private ListenerList workbenchListeners = new ListenerList( ListenerList.IDENTITY); private ServiceRegistration workbenchService; // RAP [bm]: see createAndRunWorkbench for initialization // /** // * Creates a new workbench. // * // * @param display // * the display to be used for all UI interactions with the // * workbench // * @param advisor // * the application-specific advisor that configures and // * specializes this workbench instance // */ // private Workbench(Display display, WorkbenchAdvisor advisor) { // super(); // StartupThreading.setWorkbench(this); // if (instance != null && instance.isRunning()) { // throw new IllegalStateException( // WorkbenchMessages.Workbench_CreatingWorkbenchTwice); // } // Assert.isNotNull(display); // Assert.isNotNull(advisor); // this.advisor = advisor; // this.display = display; // Workbench.instance = this; // // // for dynamic UI [This seems to be for everything that isn't handled by // // some // // subclass of RegistryManager. I think that when an extension is moved // // to the // // RegistryManager implementation, then it should be removed from the // // list in // // ExtensionEventHandler#appear. // // I've found that the new wizard extension in particular is a poor // // choice to // // use as an example, since the result of reading the registry is not // // cached // // -- so it is re-read each time. The only real contribution of this // // dialog is // // to show the user a nice dialog describing the addition.] // extensionEventHandler = new ExtensionEventHandler(this); // Platform.getExtensionRegistry().addRegistryChangeListener( // extensionEventHandler); // IServiceLocatorCreator slc = new ServiceLocatorCreator(); // serviceLocator = (ServiceLocator) slc.createServiceLocator(null, null); // serviceLocator.registerService(IServiceLocatorCreator.class, slc); // serviceLocator.registerService(IWorkbench.class, this); // } private Workbench() { extensionEventHandler = new ExtensionEventHandler(this); Platform.getExtensionRegistry().addRegistryChangeListener( extensionEventHandler); IServiceLocatorCreator slc = new ServiceLocatorCreator(); serviceLocator = (ServiceLocator) slc.createServiceLocator(null, null, new IDisposable(){ public void dispose() { final Display display = getDisplay(); if (display != null && !display.isDisposed()) { MessageDialog .openInformation( null, WorkbenchMessages.get().Workbench_NeedsClose_Title, WorkbenchMessages.get().Workbench_NeedsClose_Message); close(PlatformUI.RETURN_RESTART, true); } } }); serviceLocator.registerService(IServiceLocatorCreator.class, slc); serviceLocator.registerService(IWorkbenchLocationService.class, new WorkbenchLocationService(IServiceScopes.WORKBENCH_SCOPE, this, null, null, null, null, 0)); // added back for legacy reasons serviceLocator.registerService(IWorkbench.class, this); } // RAPEND: [bm] /** * Returns the one and only instance of the workbench, if there is one. * * @return the workbench, or <code>null</code> if the workbench has not * been created, or has been created and already completed */ public static final Workbench getInstance() { // RAP [bm]: use SSB // return instance; return SingletonUtil.getSessionInstance( Workbench.class ); // RAPEND: [bm] } /** * Creates the workbench and associates it with the the given display and * workbench advisor, and runs the workbench UI. This entails processing and * dispatching events until the workbench is closed or restarted. * <p> * This method is intended to be called by <code>PlatformUI</code>. Fails * if the workbench UI has already been created. * </p> * <p> * The display passed in must be the default display. * </p> * * @param display * the display to be used for all UI interactions with the * workbench * @param advisor * the application-specific advisor that configures and * specializes the workbench * @return return code {@link PlatformUI#RETURN_OK RETURN_OK}for normal * exit; {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the * workbench was terminated with a call to * {@link IWorkbench#restart IWorkbench.restart}; other values * reserved for future use */ public static final int createAndRunWorkbench(final Display display, final WorkbenchAdvisor advisor) { final int[] returnCode = new int[1]; Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() { public void run() { ULocale.setDefault(new ULocale(Platform.getNL() + Platform.getNLExtensions())); // create the workbench instance // RAP [bm]: // Workbench workbench = new Workbench(display, advisor); Workbench workbench = getInstance(); workbench.display = display; workbench.advisor = advisor; // RAPEND: [bm] // run the workbench event loop // RAP [rh]: cleanup when session terminates display.addListener( SWT.Dispose, new ShutdownHandler() ); // RAPEND returnCode[0] = workbench.runUI(); } }); return returnCode[0]; } /** * Creates the <code>Display</code> to be used by the workbench. * * @return the display */ public static Display createDisplay() { // setup the application name used by SWT to lookup resources on some // platforms String applicationName = WorkbenchPlugin.getDefault().getAppName(); if (applicationName != null) { Display.setAppName(applicationName); } String appVersion = WorkbenchPlugin.getDefault().getAppVersion(); if (appVersion != null) { Display.setAppVersion(appVersion); } // create the display Display newDisplay = Display.getCurrent(); // RAP [bm]: // if(newDisplay == null) { // if (Policy.DEBUG_SWT_GRAPHICS || Policy.DEBUG_SWT_DEBUG) { // DeviceData data = new DeviceData(); // if (Policy.DEBUG_SWT_GRAPHICS) { // data.tracking = true; // } // if (Policy.DEBUG_SWT_DEBUG) { // data.debug = true; // } // newDisplay = new Display(data); // } else { // newDisplay = new Display(); // } // } if(newDisplay == null) { newDisplay = new Display(); } // RAPEND: [bm] // workaround for 1GEZ9UR and 1GF07HN // RAP [bm]: Display#setWarnings // newDisplay.setWarnings(false); // Set the priority higher than normal so as to be higher // than the JobManager. Thread.currentThread().setPriority( Math.min(Thread.MAX_PRIORITY, Thread.NORM_PRIORITY + 1)); initializeImages(); return newDisplay; } // RAP [bm]: Avoid splash // /** // * Create the splash wrapper and set it to work. // */ // private void createSplashWrapper() { // final Display display = getDisplay(); // String splashLoc = System.getProperty("org.eclipse.equinox.launcher.splash.location"); //$NON-NLS-1$ // final Image background = loadImage(splashLoc); // // SafeRunnable run = new SafeRunnable() { // // public void run() throws Exception { // if (! WorkbenchPlugin.isSplashHandleSpecified()) { // createSplash = false; // return; // } // // // create the splash // getSplash(); // if (splash == null) { // createSplash = false; // return; // } // // Shell splashShell = splash.getSplash(); // if (splashShell == null) { // splashShell = WorkbenchPlugin.getSplashShell(display); // // if (splashShell == null) // return; // if (background != null) // splashShell.setBackgroundImage(background); // } // // Dictionary properties = new Hashtable(); // properties.put(Constants.SERVICE_RANKING, new Integer(Integer.MAX_VALUE)); // BundleContext context = WorkbenchPlugin.getDefault().getBundleContext(); // final ServiceRegistration registration[] = new ServiceRegistration[1]; // StartupMonitor startupMonitor = new StartupMonitor() { // // public void applicationRunning() { // splash.dispose(); // if (background != null) // background.dispose(); // registration[0].unregister(); // unregister ourself // WorkbenchPlugin.unsetSplashShell(display); // } // // public void update() { // // do nothing - we come into the picture far too late // // for this to be relevant // } // }; // registration[0] = context.registerService(StartupMonitor.class // .getName(), startupMonitor, properties); // // splash.init(splashShell); // } // /* (non-Javadoc) // * @see org.eclipse.jface.util.SafeRunnable#handleException(java.lang.Throwable) // */ // public void handleException(Throwable e) { // StatusManager.getManager().handle( // StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, // "Could not instantiate splash", e)); //$NON-NLS-1$ // createSplash = false; // splash = null; // if (background != null) // background.dispose(); // // } // }; // SafeRunner.run(run); // } // RAPEND: [bm] // RAP [bm]: not used // /** // * Load an image from a filesystem path. // * // * @param splashLoc the location to load from // * @return the image or <code>null</code> // */ // private Image loadImage(String splashLoc) { // Image background = null; // if (splashLoc != null) { // InputStream input = null; // try { // input = new BufferedInputStream(new FileInputStream(splashLoc)); // background = new Image(display, input); // } catch (SWTException e) { // StatusManager.getManager().handle( // StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e)); // } catch (IOException e) { // StatusManager.getManager().handle( // StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, e)); // } finally { // if (input != null) { // try { // input.close(); // } catch (IOException e) { // // he's done for // } // } // } // } // return background; // } // RAPEND: [bm] // RAP [bm]: no splash // /** // * Return the splash handler for this application. If none is specifically // * provided the default Eclipse implementation is returned. // * // * @return the splash handler for this application or <code>null</code> // */ // private static AbstractSplashHandler getSplash() { // if (!createSplash) // return null; // // if (splash == null) { // // IProduct product = Platform.getProduct(); // if (product != null) // splash = SplashHandlerFactory.findSplashHandlerFor(product); // // if (splash == null) // splash = new EclipseSplashHandler(); // } // return splash; // } // RAPEND: [bm] /** * Returns the testable object facade, for use by the test harness. * * @return the testable object facade */ public static WorkbenchTestable getWorkbenchTestable() { // RAP [bm]: // if (testableObject == null) { // testableObject = new WorkbenchTestable(); // } // return testableObject; Workbench instance = getInstance(); if (instance.testableObject == null) { instance.testableObject = new WorkbenchTestable(); } return instance.testableObject; // RAPEND: [bm] } /* * (non-Javadoc) Method declared on IWorkbench. */ public void addWorkbenchListener(IWorkbenchListener listener) { workbenchListeners.add(listener); } /* * (non-Javadoc) Method declared on IWorkbench. */ public void removeWorkbenchListener(IWorkbenchListener listener) { workbenchListeners.remove(listener); } /** * Fire workbench preShutdown event, stopping at the first one to veto * * @param forced * flag indicating whether the shutdown is being forced * @return <code>true</code> to allow the workbench to proceed with * shutdown, <code>false</code> to veto a non-forced shutdown */ boolean firePreShutdown(final boolean forced) { Object list[] = workbenchListeners.getListeners(); for (int i = 0; i < list.length; i++) { final IWorkbenchListener l = (IWorkbenchListener) list[i]; final boolean[] result = new boolean[] { false }; SafeRunnable.run(new SafeRunnable() { public void run() { result[0] = l.preShutdown(Workbench.this, forced); } }); if (!result[0]) { return false; } } return true; } /** * Fire workbench postShutdown event. */ void firePostShutdown() { Object list[] = workbenchListeners.getListeners(); for (int i = 0; i < list.length; i++) { final IWorkbenchListener l = (IWorkbenchListener) list[i]; SafeRunnable.run(new SafeRunnable() { public void run() { l.postShutdown(Workbench.this); } }); } } /* * (non-Javadoc) Method declared on IWorkbench. */ public void addWindowListener(IWindowListener l) { addListenerObject(l); } /* * (non-Javadoc) Method declared on IWorkbench. */ public void removeWindowListener(IWindowListener l) { removeListenerObject(l); } /** * Fire window opened event. * * @param window * The window which just opened; should not be <code>null</code>. */ protected void fireWindowOpened(final IWorkbenchWindow window) { Object list[] = getListeners(); for (int i = 0; i < list.length; i++) { final IWindowListener l = (IWindowListener) list[i]; SafeRunner.run(new SafeRunnable() { public void run() { l.windowOpened(window); } }); } } /** * Fire window closed event. * * @param window * The window which just closed; should not be <code>null</code>. */ protected void fireWindowClosed(final IWorkbenchWindow window) { if (activatedWindow == window) { // Do not hang onto it so it can be GC'ed activatedWindow = null; } Object list[] = getListeners(); for (int i = 0; i < list.length; i++) { final IWindowListener l = (IWindowListener) list[i]; SafeRunner.run(new SafeRunnable() { public void run() { l.windowClosed(window); } }); } } /** * Fire window activated event. * * @param window * The window which was just activated; should not be * <code>null</code>. */ protected void fireWindowActivated(final IWorkbenchWindow window) { Object list[] = getListeners(); for (int i = 0; i < list.length; i++) { final IWindowListener l = (IWindowListener) list[i]; SafeRunner.run(new SafeRunnable() { public void run() { l.windowActivated(window); } }); } } /** * Fire window deactivated event. * * @param window * The window which was just deactivated; should not be * <code>null</code>. */ protected void fireWindowDeactivated(final IWorkbenchWindow window) { Object list[] = getListeners(); for (int i = 0; i < list.length; i++) { final IWindowListener l = (IWindowListener) list[i]; SafeRunner.run(new SafeRunnable() { public void run() { l.windowDeactivated(window); } }); } } /** * Closes the workbench. Assumes that the busy cursor is active. * * @param force * true if the close is mandatory, and false if the close is * allowed to fail * @return true if the close succeeded, and false otherwise */ private boolean busyClose(final boolean force) { // notify the advisor of preShutdown and allow it to veto if not forced isClosing = advisor.preShutdown(); if (!force && !isClosing) { return false; } // notify regular workbench clients of preShutdown and allow them to // veto if not forced isClosing = firePreShutdown(force); if (!force && !isClosing) { return false; } // save any open editors if they are dirty // RAP [bm]: added session condition if(!sessionInvalidated) { // RAPEND: [bm] isClosing = saveAllEditors(!force); if (!force && !isClosing) { return false; } } boolean closeEditors = !force && PrefUtil.getAPIPreferenceStore().getBoolean( IWorkbenchPreferenceConstants.CLOSE_EDITORS_ON_EXIT); if (closeEditors) { SafeRunner.run(new SafeRunnable() { public void run() { IWorkbenchWindow windows[] = getWorkbenchWindows(); for (int i = 0; i < windows.length; i++) { IWorkbenchPage pages[] = windows[i].getPages(); for (int j = 0; j < pages.length; j++) { isClosing = isClosing && pages[j].closeAllEditors(false); } } } }); if (!force && !isClosing) { return false; } } if (getWorkbenchConfigurer().getSaveAndRestore()) { SafeRunner.run(new SafeRunnable() { public void run() { XMLMemento mem = recordWorkbenchState(); // Save the IMemento to a file. saveMementoToFile(mem); } public void handleException(Throwable e) { String message; if (e.getMessage() == null) { message = WorkbenchMessages.get().ErrorClosingNoArg; } else { message = NLS.bind( WorkbenchMessages.get().ErrorClosingOneArg, e .getMessage()); } if (!MessageDialog.openQuestion(null, WorkbenchMessages.get().Error, message)) { isClosing = false; } } }); } if (!force && !isClosing) { return false; } // RAP [bm]: i18n // SafeRunner.run(new SafeRunnable(WorkbenchMessages.ErrorClosing) { SafeRunner.run(new SafeRunnable(WorkbenchMessages.get().ErrorClosing) { public void run() { if (isClosing || force) { isClosing = windowManager.close(); } } }); if (!force && !isClosing) { return false; } shutdown(); runEventLoop = false; return true; } /* (non-Javadoc) * @see org.eclipse.ui.IWorkbench#saveAllEditors(boolean) */ public boolean saveAllEditors(boolean confirm) { final boolean finalConfirm = confirm; final boolean[] result = new boolean[1]; result[0] = true; SafeRunner.run(new SafeRunnable(WorkbenchMessages.get().ErrorClosing) { public void run() { // Collect dirtyParts ArrayList dirtyParts = new ArrayList(); ArrayList dirtyEditorsInput = new ArrayList(); IWorkbenchWindow windows[] = getWorkbenchWindows(); for (int i = 0; i < windows.length; i++) { IWorkbenchPage pages[] = windows[i].getPages(); for (int j = 0; j < pages.length; j++) { WorkbenchPage page = (WorkbenchPage) pages[j]; ISaveablePart[] parts = page.getDirtyParts(); for (int k = 0; k < parts.length; k++) { ISaveablePart part = parts[k]; if (part.isSaveOnCloseNeeded()) { if (part instanceof IEditorPart) { IEditorPart editor = (IEditorPart) part; if (!dirtyEditorsInput.contains(editor .getEditorInput())) { dirtyParts.add(editor); dirtyEditorsInput.add(editor .getEditorInput()); } } else { dirtyParts.add(part); } } } } } IShellProvider shellProvider; IRunnableContext runnableContext; IWorkbenchWindow w = getActiveWorkbenchWindow(); if (w == null && windows.length > 0) { w = windows[0]; } if (w != null) { shellProvider = w; runnableContext = w; } else { shellProvider = new IShellProvider() { public Shell getShell() { return null; } }; runnableContext = new ProgressMonitorDialog(null); } // The fourth parameter is true to also save saveables from // non-part sources, see bug 139004. result[0] = EditorManager.saveAll(dirtyParts, finalConfirm, false, true, runnableContext, shellProvider); } }); return result[0]; } /** * Opens a new workbench window and page with a specific perspective. * * Assumes that busy cursor is active. */ private IWorkbenchWindow busyOpenWorkbenchWindow(final String perspID, final IAdaptable input) throws WorkbenchException { // Create a workbench window (becomes active window) final WorkbenchWindow newWindowArray[] = new WorkbenchWindow[1]; StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() { public void runWithException() { newWindowArray[0] = newWorkbenchWindow(); } }); final WorkbenchWindow newWindow = newWindowArray[0]; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { newWindow.create(); // must be created before adding to window // manager } }); windowManager.add(newWindow); final WorkbenchException [] exceptions = new WorkbenchException[1]; // Create the initial page. if (perspID != null) { StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() { public void runWithException() { try { newWindow.busyOpenPage(perspID, input); } catch (WorkbenchException e) { windowManager.remove(newWindow); exceptions[0] = e; } }}); } if (exceptions[0] != null) throw exceptions[0]; // RAP [bm]: this is added to have filter capability in ActiveShellSourceProvider newWindow.getShell().addListener(SWT.Activate, new Listener() { public void handleEvent(Event event) { } }); // Open window after opening page, to avoid flicker. StartupThreading.runWithWorkbenchExceptions(new StartupRunnable() { public void runWithException() { newWindow.open(); } }); return newWindow; } /* * (non-Javadoc) Method declared on IWorkbench. */ public boolean close() { return close(PlatformUI.RETURN_OK, false); } /** * Closes the workbench, returning the given return code from the run * method. If forced, the workbench is closed no matter what. * * @param returnCode * {@link PlatformUI#RETURN_OK RETURN_OK}for normal exit; * {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the * workbench was terminated with a call to * {@link IWorkbench#restart IWorkbench.restart}; * {@link PlatformUI#RETURN_EMERGENCY_CLOSE} for an emergency * shutdown * {@link PlatformUI#RETURN_UNSTARTABLE RETURN_UNSTARTABLE}if * the workbench could not be started; other values reserved for * future use * * @param force * true to force the workbench close, and false for a "soft" * close that can be canceled * @return true if the close was successful, and false if the close was * canceled */ /* package */ boolean close(int returnCode, final boolean force) { // RAP [fappel]: take care of the started flag // this.returnCode = returnCode; // final boolean[] ret = new boolean[1]; // BusyIndicator.showWhile(null, new Runnable() { // public void run() { // ret[0] = busyClose(force); // } // }); // return ret[0]; try { this.returnCode = returnCode; final boolean[] ret = new boolean[1]; BusyIndicator.showWhile(null, new Runnable() { public void run() { ret[0] = busyClose(force); } }); return ret[0]; } finally { started = false; } } /* * (non-Javadoc) Method declared on IWorkbench. */ public IWorkbenchWindow getActiveWorkbenchWindow() { // Return null if called from a non-UI thread. // This is not spec'ed behaviour and is misleading, however this is how // it // worked in 2.1 and we cannot change it now. // For more details, see [Bug 57384] [RCP] Main window not active on // startup if (Display.getCurrent() == null) { return null; } // Look at the current shell and up its parent // hierarchy for a workbench window. Control shell = display.getActiveShell(); while (shell != null) { Object data = shell.getData(); if (data instanceof IWorkbenchWindow) { return (IWorkbenchWindow) data; } shell = shell.getParent(); } // Look for the window that was last known being // the active one WorkbenchWindow win = getActivatedWindow(); if (win != null) { return win; } // Look at all the shells and pick the first one // that is a workbench window. Shell shells[] = display.getShells(); for (int i = 0; i < shells.length; i++) { Object data = shells[i].getData(); if (data instanceof IWorkbenchWindow) { return (IWorkbenchWindow) data; } } // Can't find anything! return null; } /* * Returns the editor history. */ public EditorHistory getEditorHistory() { if (editorHistory == null) { editorHistory = new EditorHistory(); } return editorHistory; } /* * (non-Javadoc) Method declared on IWorkbench. */ public IEditorRegistry getEditorRegistry() { return WorkbenchPlugin.getDefault().getEditorRegistry(); } /* * Returns the number for a new window. This will be the first number > 0 * which is not used to identify another window in the workbench. */ private int getNewWindowNumber() { // Get window list. Window[] windows = windowManager.getWindows(); int count = windows.length; // Create an array of booleans (size = window count). // Cross off every number found in the window list. boolean checkArray[] = new boolean[count]; for (int nX = 0; nX < count; nX++) { if (windows[nX] instanceof WorkbenchWindow) { WorkbenchWindow ww = (WorkbenchWindow) windows[nX]; int index = ww.getNumber() - 1; if (index >= 0 && index < count) { checkArray[index] = true; } } } // Return first index which is not used. // If no empty index was found then every slot is full. // Return next index. for (int index = 0; index < count; index++) { if (!checkArray[index]) { return index + 1; } } return count + 1; } /* * (non-Javadoc) Method declared on IWorkbench. */ public IWorkbenchOperationSupport getOperationSupport() { return WorkbenchPlugin.getDefault().getOperationSupport(); } /* * (non-Javadoc) Method declared on IWorkbench. */ public IPerspectiveRegistry getPerspectiveRegistry() { return WorkbenchPlugin.getDefault().getPerspectiveRegistry(); } /* * (non-Javadoc) Method declared on IWorkbench. */ public PreferenceManager getPreferenceManager() { return WorkbenchPlugin.getDefault().getPreferenceManager(); } /* * (non-Javadoc) Method declared on IWorkbench. */ public IPreferenceStore getPreferenceStore() { return WorkbenchPlugin.getDefault().getPreferenceStore(); } /* * (non-Javadoc) Method declared on IWorkbench. */ public ISharedImages getSharedImages() { return WorkbenchPlugin.getDefault().getSharedImages(); } /** * Returns the window manager for this workbench. * * @return the window manager */ /* package */ WindowManager getWindowManager() { return windowManager; } /* * Answer the workbench state file. */ // RAP [fappel]: use SettingStore mechanism for cluster support // private File getWorkbenchStateFile() { // IPath path = WorkbenchPlugin.getDefault().getDataLocation(); // if (path == null) { // return null; // } // path = path.append(DEFAULT_WORKBENCH_STATE_FILENAME); // return path.toFile(); // } /* * (non-Javadoc) Method declared on IWorkbench. */ public int getWorkbenchWindowCount() { return windowManager.getWindowCount(); } /* * (non-Javadoc) Method declared on IWorkbench. */ public IWorkbenchWindow[] getWorkbenchWindows() { Window[] windows = windowManager.getWindows(); IWorkbenchWindow[] dwindows = new IWorkbenchWindow[windows.length]; System.arraycopy(windows, 0, dwindows, 0, windows.length); return dwindows; } /* * (non-Javadoc) Method declared on IWorkbench. */ public IWorkingSetManager getWorkingSetManager() { return WorkbenchPlugin.getDefault().getWorkingSetManager(); } /** * {@inheritDoc} */ public ILocalWorkingSetManager createLocalWorkingSetManager() { return new LocalWorkingSetManager(WorkbenchPlugin.getDefault() .getBundleContext()); } /** * Initializes the workbench now that the display is created. * * @return true if init succeeded. */ private boolean init() { // RAP [fappel]: take care of the started flag started = true; // setup debug mode if required. if (WorkbenchPlugin.getDefault().isDebugging()) { WorkbenchPlugin.DEBUG = true; ModalContext.setDebugMode(true); } // Set up the JFace preference store JFaceUtil.initializeJFacePreferences(); // create workbench window manager windowManager = new WindowManager(); IIntroRegistry introRegistry = WorkbenchPlugin.getDefault() .getIntroRegistry(); if (introRegistry.getIntroCount() > 0) { // RAP [bm]: no product support - use branding instead // IProduct product = Platform.getProduct(); // if (product != null) { // introDescriptor = (IntroDescriptor) introRegistry // .getIntroForProduct(product.getId()); // } String brandingId = BrandingUtil.getCurrentBrandingId(); if (brandingId != null) { introDescriptor = (IntroDescriptor) introRegistry .getIntroForBranding(brandingId); } // ENDRAP } // TODO Correctly order service initialization // there needs to be some serious consideration given to // the services, and hooking them up in the correct order final EvaluationService restrictionService = new EvaluationService(); final EvaluationService evaluationService = new EvaluationService(); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { serviceLocator.registerService(IEvaluationService.class, evaluationService); } }); // Initialize the activity support. workbenchActivitySupport = new WorkbenchActivitySupport(); activityHelper = ActivityPersistanceHelper.getInstance(); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { WorkbenchImages.getImageRegistry(); } }); initializeDefaultServices(); initializeFonts(); initializeColors(); initializeApplicationColors(); // now that the workbench is sufficiently initialized, let the advisor // have a turn. StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { advisor.internalBasicInitialize(getWorkbenchConfigurer()); } }); // configure use of color icons in toolbars boolean useColorIcons = PrefUtil.getInternalPreferenceStore() .getBoolean(IPreferenceConstants.COLOR_ICONS); ActionContributionItem.setUseColorIconsInToolbars(useColorIcons); // initialize workbench single-click vs double-click behavior initializeSingleClickOption(); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { ((GrabFocus) Tweaklets.get(GrabFocus.KEY)) .init(getDisplay()); } }); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { startSourceProviders(); } }); // attempt to restore a previous workbench state try { UIStats.start(UIStats.RESTORE_WORKBENCH, "Workbench"); //$NON-NLS-1$ final boolean bail [] = new boolean[1]; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable { advisor.preStartup(); if (isClosing() || !advisor.openWindows()) { bail[0] = true; } }}); if (bail[0]) return false; } finally { UIStats.end(UIStats.RESTORE_WORKBENCH, this, "Workbench"); //$NON-NLS-1$ } forceOpenPerspective(); return true; } /** * Establishes the relationship between JFace actions and the command * manager. */ private void initializeCommandResolver() { ExternalActionManager.getInstance().setCallback( new CommandCallback(bindingManager, commandManager, new IActiveChecker() { public final boolean isActive(final String commandId) { return workbenchActivitySupport .getActivityManager().getIdentifier( commandId).isEnabled(); } }, new IExecuteApplicable() { public boolean isApplicable(IAction action) { return !(action instanceof CommandAction); } })); } /** * Initialize colors defined by the new colorDefinitions extension point. * Note this will be rolled into initializeColors() at some point. */ private void initializeApplicationColors() { StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { ColorDefinition[] colorDefinitions = WorkbenchPlugin .getDefault().getThemeRegistry().getColors(); ThemeElementHelper.populateRegistry(getThemeManager().getTheme( IThemeManager.DEFAULT_THEME), colorDefinitions, PrefUtil.getInternalPreferenceStore()); } }); } private void initializeSingleClickOption() { IPreferenceStore store = WorkbenchPlugin.getDefault() .getPreferenceStore(); boolean openOnSingleClick = store .getBoolean(IPreferenceConstants.OPEN_ON_SINGLE_CLICK); boolean selectOnHover = store .getBoolean(IPreferenceConstants.SELECT_ON_HOVER); boolean openAfterDelay = store .getBoolean(IPreferenceConstants.OPEN_AFTER_DELAY); int singleClickMethod = openOnSingleClick ? OpenStrategy.SINGLE_CLICK : OpenStrategy.DOUBLE_CLICK; if (openOnSingleClick) { if (selectOnHover) { singleClickMethod |= OpenStrategy.SELECT_ON_HOVER; } if (openAfterDelay) { singleClickMethod |= OpenStrategy.ARROW_KEYS_OPEN; } } OpenStrategy.setOpenMethod(singleClickMethod); } /* * Initializes the workbench fonts with the stored values. */ private void initializeFonts() { StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { FontDefinition[] fontDefinitions = WorkbenchPlugin.getDefault() .getThemeRegistry().getFonts(); ThemeElementHelper.populateRegistry(getThemeManager() .getCurrentTheme(), fontDefinitions, PrefUtil .getInternalPreferenceStore()); } }); } /* * Initialize the workbench images. * * @param windowImages An array of the descriptors of the images to be used * in the corner of each window, or <code>null</code> if none. It is * expected that the array will contain the same icon, rendered at different * sizes. */ private static void initializeImages() { ImageDescriptor[] windowImages = WorkbenchPlugin.getDefault() .getWindowImages(); if (windowImages == null) { return; } Image[] images = new Image[windowImages.length]; for (int i = 0; i < windowImages.length; ++i) { images[i] = windowImages[i].createImage(); } Window.setDefaultImages(images); } /* * Take the workbenches' images out of the shared registry. */ private void uninitializeImages() { WorkbenchImages.dispose(); Window.setDefaultImage(null); // RAP [bm]: Image#dispose // Image[] images = Window.getDefaultImages(); // for (int i = 0; i < images.length; i++) { // images[i].dispose(); // } // RAPEND: [bm] } /* * Initialize the workbench colors. */ private void initializeColors() { StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { WorkbenchColors.startup(); }}); } /* * (non-Javadoc) Method declared on IWorkbench. */ public boolean isClosing() { return isClosing; } /** * Initializes all of the default services for the workbench. For * initializing the command-based services, this also parses the registry * and hooks up all the required listeners. */ private final void initializeDefaultServices() { final IContributionService contributionService = new ContributionService( getAdvisor()); serviceLocator.registerService(IContributionService.class, contributionService); // TODO Correctly order service initialization // there needs to be some serious consideration given to // the services, and hooking them up in the correct order StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { serviceLocator.registerService(ISaveablesLifecycleListener.class, new SaveablesList()); }}); /* * Phase 1 of the initialization of commands. When this phase completes, * all the services and managers will exist, and be accessible via the * getService(Object) method. */ StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { Command.DEBUG_COMMAND_EXECUTION = Policy.DEBUG_COMMANDS; commandManager = new CommandManager(); }}); final CommandService [] commandService = new CommandService[1]; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { commandService[0] = new CommandService(commandManager); commandService[0].readRegistry(); serviceLocator.registerService(ICommandService.class, commandService[0]); }}); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { ContextManager.DEBUG = Policy.DEBUG_CONTEXTS; contextManager = new ContextManager(); }}); final IContextService contextService = new ContextService( contextManager); StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { contextService.readRegistry(); }}); serviceLocator.registerService(IContextService.class, contextService); final IBindingService [] bindingService = new BindingService[1]; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { BindingManager.DEBUG = Policy.DEBUG_KEY_BINDINGS; bindingManager = new BindingManager(contextManager, commandManager); bindingService[0] = new BindingService( bindingManager, commandService[0], Workbench.this); }}); bindingService[0].readRegistryAndPreferences(commandService[0]); serviceLocator.registerService(IBindingService.class, bindingService[0]); final CommandImageManager commandImageManager = new CommandImageManager(); final CommandImageService commandImageService = new CommandImageService( commandImageManager, commandService[0]); commandImageService.readRegistry(); serviceLocator.registerService(ICommandImageService.class, commandImageService); final WorkbenchMenuService menuService = new WorkbenchMenuService(serviceLocator); serviceLocator.registerService(IMenuService.class, menuService); // the service must be registered before it is initialized - its // initialization uses the service locator to address a dependency on // the menu service StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { menuService.readRegistry(); }}); // the source providers are now initialized in phase 3 /* * Phase 2 of the initialization of commands. This handles the creation * of wrappers for legacy APIs. By the time this phase completes, any * code trying to access commands through legacy APIs should work. */ final IHandlerService[] handlerService = new IHandlerService[1]; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { handlerService[0] = (IHandlerService) serviceLocator .getService(IHandlerService.class); } }); workbenchContextSupport = new WorkbenchContextSupport(this, contextManager); // RAP [bm] command service disabled // workbenchCommandSupport = new WorkbenchCommandSupport(bindingManager, // commandManager, contextManager, handlerService[0]); initializeCommandResolver(); addWindowListener(windowListener); bindingManager.addBindingManagerListener(bindingManagerListener); serviceLocator.registerService(ISelectionConversionService.class, new SelectionConversionService()); } /** * Returns true if the Workbench is in the process of starting. * * @return <code>true</code> if the Workbench is starting, but not yet * running the event loop. */ public boolean isStarting() { return isStarting && isRunning(); } /* * Creates a new workbench window. * * @return the new workbench window */ private WorkbenchWindow newWorkbenchWindow() { WorkbenchWindow wbw = ((WorkbenchImplementation) Tweaklets .get(WorkbenchImplementation.KEY)).createWorkbenchWindow(getNewWindowNumber()); return wbw; } /* * If a perspective was specified on the command line (-perspective) then * force that perspective to open in the active window. */ private void forceOpenPerspective() { if (getWorkbenchWindowCount() == 0) { // there should be an open window by now, bail out. return; } String perspId = null; String[] commandLineArgs = Platform.getCommandLineArgs(); for (int i = 0; i < commandLineArgs.length - 1; i++) { if (commandLineArgs[i].equalsIgnoreCase("-perspective")) { //$NON-NLS-1$ perspId = commandLineArgs[i + 1]; break; } } if (perspId == null) { return; } IPerspectiveDescriptor desc = getPerspectiveRegistry() .findPerspectiveWithId(perspId); if (desc == null) { return; } IWorkbenchWindow win = getActiveWorkbenchWindow(); if (win == null) { win = getWorkbenchWindows()[0]; } final String threadPerspId = perspId; final IWorkbenchWindow threadWin = win; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable { try { showPerspective(threadPerspId, threadWin); } catch (WorkbenchException e) { String msg = "Workbench exception showing specified command line perspective on startup."; //$NON-NLS-1$ WorkbenchPlugin.log(msg, new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, 0, msg, e)); } }}); } /** * Opens the initial workbench window. */ /* package */void openFirstTimeWindow() { final boolean showProgress = PrefUtil.getAPIPreferenceStore() .getBoolean( IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP); if (!showProgress) { doOpenFirstTimeWindow(); } else { // We don't know how many plug-ins will be loaded, // assume we are loading a tenth of the installed plug-ins. // (The Eclipse SDK loads 7 of 86 plug-ins at startup as of // 2005-5-20) final int expectedProgressCount = Math.max(1, WorkbenchPlugin .getDefault().getBundleCount() / 10); runStartupWithProgress(expectedProgressCount, new Runnable() { public void run() { doOpenFirstTimeWindow(); } }); } } private void runStartupWithProgress(final int expectedProgressCount, final Runnable runnable) { // RAP [bm]: no chance to show progress, just start up runnable.run(); // progressCount = 0; // final double cutoff = 0.95; // // AbstractSplashHandler handler = getSplash(); // IProgressMonitor progressMonitor = null; // if (handler != null) // progressMonitor = handler.getBundleProgressMonitor(); // // if (progressMonitor == null) { // // cannot report progress (e.g. if the splash screen is not showing) // // fall back to starting without showing progress. // runnable.run(); // } else { // Shell shell = null; // if (handler != null) { // shell = handler.getSplash(); // } // progressMonitor = new TaskBarDelegatingProgressMontior(progressMonitor, shell); // progressMonitor.beginTask("", expectedProgressCount); //$NON-NLS-1$ // SynchronousBundleListener bundleListener = new StartupProgressBundleListener( // progressMonitor, (int) (expectedProgressCount * cutoff)); // WorkbenchPlugin.getDefault().addBundleListener(bundleListener); // try { // runnable.run(); // progressMonitor.subTask(WorkbenchMessages.Startup_Done); // int remainingWork = expectedProgressCount // - Math.min(progressCount, // (int) (expectedProgressCount * cutoff)); // progressMonitor.worked(remainingWork); // progressMonitor.done(); // } finally { // WorkbenchPlugin.getDefault().removeBundleListener( // bundleListener); // } // } // RAPEND: [bm] } private void doOpenFirstTimeWindow() { try { final IAdaptable input [] = new IAdaptable[1]; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable { input[0] = getDefaultPageInput(); }}); busyOpenWorkbenchWindow(getPerspectiveRegistry() .getDefaultPerspective(), input[0]); } catch (final WorkbenchException e) { // Don't use the window's shell as the dialog parent, // as the window is not open yet (bug 76724). StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable { ErrorDialog.openError(null, WorkbenchMessages.get().Problems_Opening_Page, e.getMessage(), e .getStatus()); }}); } } /* * Restores the workbench UI from the workbench state file (workbench.xml). * * @return a status object indicating OK if a window was opened, * RESTORE_CODE_RESET if no window was opened but one should be, and * RESTORE_CODE_EXIT if the workbench should close immediately */ /* package */IStatus restoreState() { if (!getWorkbenchConfigurer().getSaveAndRestore()) { String msg = WorkbenchMessages.get().Workbench_restoreDisabled; return new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH, IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null); } // RAP [fappel]: need solution that allows cluster support // // Read the workbench state file. // final File stateFile = getWorkbenchStateFile(); // // If there is no state file cause one to open. // if (stateFile == null || !stateFile.exists()) { // String msg = WorkbenchMessages.get().Workbench_noStateToRestore; // return new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH, // IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null); // } final SettingStore settingStore = RWT.getSettingStore(); final String state = settingStore.getAttribute( KEY_WORKBENCH_STATE ); if( state == null ) { String msg = WorkbenchMessages.get().Workbench_noStateToRestore; return new Status( IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH, IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null ); } final IStatus result[] = { Status.OK_STATUS }; SafeRunner.run(new SafeRunnable(WorkbenchMessages.get().ErrorReadingState) { public void run() throws Exception { // RAP [fappel]: need solution that allows cluster support // FileInputStream input = new FileInputStream(stateFile); // BufferedReader reader = new BufferedReader( // new InputStreamReader(input, "utf-8")); //$NON-NLS-1$ StringReader reader = new StringReader( state ); IMemento memento = XMLMemento.createReadRoot(reader); // Validate known version format String version = memento .getString(IWorkbenchConstants.TAG_VERSION); boolean valid = false; for (int i = 0; i < VERSION_STRING.length; i++) { if (VERSION_STRING[i].equals(version)) { valid = true; break; } } if (!valid) { reader.close(); String msg = WorkbenchMessages.get().Invalid_workbench_state_ve; MessageDialog.openError((Shell) null, WorkbenchMessages.get().Restoring_Problems, msg); // RAP [fappel]: need solution that allows cluster support // stateFile.delete(); settingStore.removeAttribute( KEY_WORKBENCH_STATE ); result[0] = new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH, IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null); return; } // Validate compatible version format // We no longer support the release 1.0 format if (VERSION_STRING[0].equals(version)) { reader.close(); String msg = WorkbenchMessages.get().Workbench_incompatibleSavedStateVersion; boolean ignoreSavedState = new MessageDialog(null, WorkbenchMessages.get().Workbench_incompatibleUIState, null, msg, MessageDialog.WARNING, new String[] { IDialogConstants.get().OK_LABEL, IDialogConstants.get().CANCEL_LABEL }, 0).open() == 0; // OK is the default if (ignoreSavedState) { // RAP [fappel]: need solution that allows cluster support // stateFile.delete(); settingStore.removeAttribute( KEY_WORKBENCH_STATE ); result[0] = new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH, IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null); } else { result[0] = new Status(IStatus.WARNING, WorkbenchPlugin.PI_WORKBENCH, IWorkbenchConfigurer.RESTORE_CODE_EXIT, msg, null); } return; } // Restore the saved state final IStatus restoreResult = restoreState(memento); reader.close(); if (restoreResult.getSeverity() == IStatus.ERROR) { StartupThreading .runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable { ErrorDialog .openError( null, WorkbenchMessages.get().Workspace_problemsTitle, WorkbenchMessages.get().Workbench_problemsRestoringMsg, restoreResult); } }); } } public void handleException(final Throwable e) { StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { handle(e); String msg = e.getMessage() == null ? "" : e.getMessage(); //$NON-NLS-1$ result[0] = new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH, IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, e); // RAP [fappel]: need solution that allows cluster support // stateFile.delete(); try { settingStore.removeAttribute( KEY_WORKBENCH_STATE ); } catch( final IOException exception ) { WorkbenchPlugin.log( WorkbenchMessages.get().Workbench_problemsRestoringMsg, exception ); } }}); } private void handle(final Throwable e) { super.handleException(e); } }); // ensure at least one window was opened if (result[0].isOK() && windowManager.getWindows().length == 0) { String msg = WorkbenchMessages.get().Workbench_noWindowsRestored; result[0] = new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH, IWorkbenchConfigurer.RESTORE_CODE_RESET, msg, null); } return result[0]; } /* * (non-Javadoc) Method declared on IWorkbench. */ public IWorkbenchWindow openWorkbenchWindow(IAdaptable input) throws WorkbenchException { return openWorkbenchWindow(getPerspectiveRegistry() .getDefaultPerspective(), input); } /* * (non-Javadoc) Method declared on IWorkbench. */ public IWorkbenchWindow openWorkbenchWindow(final String perspID, final IAdaptable input) throws WorkbenchException { // Run op in busy cursor. final Object[] result = new Object[1]; BusyIndicator.showWhile(null, new Runnable() { public void run() { try { result[0] = busyOpenWorkbenchWindow(perspID, input); } catch (WorkbenchException e) { result[0] = e; } } }); if (result[0] instanceof IWorkbenchWindow) { return (IWorkbenchWindow) result[0]; } else if (result[0] instanceof WorkbenchException) { throw (WorkbenchException) result[0]; } else { throw new WorkbenchException( WorkbenchMessages.get().Abnormal_Workbench_Conditi); } } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#restoreWorkbenchWindow(org.eclipse.ui.IMemento) */ IWorkbenchWindow restoreWorkbenchWindow(IMemento memento) throws WorkbenchException { WorkbenchWindow newWindow = newWorkbenchWindow(); newWindow.create(); windowManager.add(newWindow); // whether the window was opened boolean opened = false; try { newWindow.restoreState(memento, null); newWindow.fireWindowRestored(); newWindow.open(); opened = true; } finally { if (!opened) { newWindow.close(); } } return newWindow; } /* * Record the workbench UI in a document */ private XMLMemento recordWorkbenchState() { XMLMemento memento = XMLMemento .createWriteRoot(IWorkbenchConstants.TAG_WORKBENCH); final IStatus status = saveState(memento); if (status.getSeverity() != IStatus.OK) { // don't use newWindow as parent because it has not yet been opened // (bug 76724) StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable { ErrorDialog.openError(null, WorkbenchMessages.get().Workbench_problemsSaving, WorkbenchMessages.get().Workbench_problemsSavingMsg, status); }}); } return memento; } // RAP [bm]: no restart // /* // * (non-Javadoc) Method declared on IWorkbench. // */ // public boolean restart() { // // this is the return code from run() to trigger a restart // return close(PlatformUI.RETURN_RESTART, false); // } /* * Restores the state of the previously saved workbench */ private IStatus restoreState(final IMemento memento) { final MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.get().Workbench_problemsRestoring, null); final boolean showProgress = PrefUtil.getAPIPreferenceStore() .getBoolean( IWorkbenchPreferenceConstants.SHOW_PROGRESS_ON_STARTUP); try { /* * Restored windows will be set in the createdWindows field to be * used by the openWindowsAfterRestore() method */ if (!showProgress) { doRestoreState(memento, result); } else { // Retrieve how many plug-ins were loaded while restoring the // workbench Integer lastProgressCount = memento .getInteger(IWorkbenchConstants.TAG_PROGRESS_COUNT); // If we don't know how many plug-ins were loaded last time, // assume we are loading half of the installed plug-ins. final int expectedProgressCount = Math.max(1, lastProgressCount == null ? WorkbenchPlugin .getDefault().getBundleCount() / 2 : lastProgressCount.intValue()); runStartupWithProgress(expectedProgressCount, new Runnable() { public void run() { doRestoreState(memento, result); } }); } } finally { openWindowsAfterRestore(); } return result; } /** * Returns the contribution infos for plug-ins that extend the * <code>org.eclipse.ui.startup</code> extension point. * * @return the ids of all plug-ins containing 1 or more startup extensions */ public ContributionInfo[] getEarlyActivatedPlugins() { // RAP [bm]: namespace IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint( PlatformUI.PLUGIN_EXTENSION_NAME_SPACE, IWorkbenchRegistryConstants.PL_STARTUP); IExtension[] extensions = point.getExtensions(); ArrayList pluginIds = new ArrayList(extensions.length); for (int i = 0; i < extensions.length; i++) { String id = extensions[i].getNamespace(); if (!pluginIds.contains(id)) { pluginIds.add(id); } } ContributionInfo[] result = new ContributionInfo[pluginIds.size()]; for (int i = 0; i < result.length; i++) { // RAP [if]: need session aware messages // result[i] = new ContributionInfo((String) pluginIds.get(i), // ContributionInfoMessages.ContributionInfo_EarlyStartupPlugin, null); result[i] = new ContributionInfo((String) pluginIds.get(i), ContributionInfoMessages.get().ContributionInfo_EarlyStartupPlugin, null); } return result; } /** * Returns the ids of the early activated plug-ins that have been disabled * by the user. * * @return the ids of the early activated plug-ins that have been disabled * by the user */ public String[] getDisabledEarlyActivatedPlugins() { String pref = PrefUtil.getInternalPreferenceStore().getString( IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP); return Util.getArrayFromList(pref, ";"); //$NON-NLS-1$ } private void startSourceProviders() { /* * Phase 3 of the initialization of commands. The source providers that * the workbench provides are creating and registered with the above * services. These source providers notify the services when particular * pieces of workbench state change. */ final IEvaluationService evaluationService = (IEvaluationService) serviceLocator .getService(IEvaluationService.class); final IContextService contextService = (IContextService) serviceLocator .getService(IContextService.class); final SourceProviderService sourceProviderService = new SourceProviderService( serviceLocator); serviceLocator.registerService(ISourceProviderService.class, sourceProviderService); SafeRunner.run(new ISafeRunnable() { public void run() throws Exception { // this currently instantiates all players ... sigh sourceProviderService.readRegistry(); ISourceProvider[] sp = sourceProviderService.getSourceProviders(); for (int i = 0; i < sp.length; i++) { evaluationService.addSourceProvider(sp[i]); if (!(sp[i] instanceof ActiveContextSourceProvider)) { contextService.addSourceProvider(sp[i]); } } } public void handleException(Throwable exception) { WorkbenchPlugin.log("Failed to initialize a source provider", exception); //$NON-NLS-1$ } }); SafeRunner.run(new ISafeRunnable() { public void run() throws Exception { // these guys are need to provide the variables they say // they source actionSetSourceProvider = (ActionSetSourceProvider) sourceProviderService .getSourceProvider(ISources.ACTIVE_ACTION_SETS_NAME); FocusControlSourceProvider focusControl = (FocusControlSourceProvider) sourceProviderService .getSourceProvider(ISources.ACTIVE_FOCUS_CONTROL_ID_NAME); serviceLocator.registerService(IFocusService.class, focusControl); menuSourceProvider = (MenuSourceProvider) sourceProviderService .getSourceProvider(ISources.ACTIVE_MENU_NAME); } public void handleException(Throwable exception) { WorkbenchPlugin.log("Failed to initialize a source provider", exception); //$NON-NLS-1$ } }); } /* * Starts all plugins that extend the <code> org.eclipse.ui.startup </code> * extension point, and that the user has not disabled via the preference * page. */ private void startPlugins() { IExtensionRegistry registry = Platform.getExtensionRegistry(); // bug 55901: don't use getConfigElements directly, for pre-3.0 // compat, make sure to allow both missing class // attribute and a missing startup element IExtensionPoint point = registry.getExtensionPoint( PlatformUI.PLUGIN_EXTENSION_NAME_SPACE, IWorkbenchRegistryConstants.PL_STARTUP); final IExtension[] extensions = point.getExtensions(); if (extensions.length == 0) { return; } Job job = new Job("Workbench early startup") { //$NON-NLS-1$ protected IStatus run(final IProgressMonitor monitor) { final IStatus[] result = { Status.OK_STATUS }; // RAP [rh] fake service context RWT.getUISession( display ).exec( new Runnable() { public void run() { HashSet disabledPlugins = new HashSet(Arrays .asList(getDisabledEarlyActivatedPlugins())); monitor.beginTask(WorkbenchMessages.get().Workbench_startingPlugins, extensions.length); for (int i = 0; i < extensions.length; ++i) { if (monitor.isCanceled() || !isRunning()) { result[ 0 ] = Status.CANCEL_STATUS; return; } IExtension extension = extensions[i]; // if the plugin is not in the set of disabled plugins, then // execute the code to start it if (!disabledPlugins.contains(extension.getNamespace())) { monitor.subTask(extension.getNamespace()); SafeRunner.run(new EarlyStartupRunnable(extension)); } monitor.worked(1); } monitor.done(); } } ); return result[ 0 ]; } public boolean belongsTo(Object family) { return EARLY_STARTUP_FAMILY.equals(family); } }; job.setSystem(true); job.schedule(); } /** * Internal method for running the workbench UI. This entails processing and * dispatching events until the workbench is closed or restarted. * * @return return code {@link PlatformUI#RETURN_OK RETURN_OK}for normal * exit; {@link PlatformUI#RETURN_RESTART RETURN_RESTART}if the * workbench was terminated with a call to * {@link IWorkbench#restart IWorkbench.restart}; * {@link PlatformUI#RETURN_UNSTARTABLE RETURN_UNSTARTABLE}if the * workbench could not be started; other values reserved for future * use */ private int runUI() { UIStats.start(UIStats.START_WORKBENCH, "Workbench"); //$NON-NLS-1$ // deadlock code boolean avoidDeadlock = true; String[] commandLineArgs = Platform.getCommandLineArgs(); for (int i = 0; i < commandLineArgs.length; i++) { if (commandLineArgs[i].equalsIgnoreCase("-allowDeadlock")) { //$NON-NLS-1$ avoidDeadlock = false; } } final UISynchronizer synchronizer; if (avoidDeadlock) { UILockListener uiLockListener = new UILockListener(display); Job.getJobManager().setLockListener(uiLockListener); synchronizer = new UISynchronizer(display, uiLockListener); display .setSynchronizer(synchronizer); // declare the main thread to be a startup thread. UISynchronizer.startupThread.set(Boolean.TRUE); } else synchronizer = null; // // prime the splash nice and early // if (createSplash) // createSplashWrapper(); // RAPEND: [bm] // activate styling if available Bundle stylingBundle = Platform.getBundle("org.eclipse.e4.ui.css.swt.theme"); //$NON-NLS-1$ if (BundleUtility.isReady(stylingBundle)) { try { Class c = stylingBundle .loadClass("org.eclipse.e4.ui.css.swt.internal.theme.BootstrapTheme3x"); //$NON-NLS-1$ Constructor constructor = c.getConstructor(new Class[] { Display.class }); constructor.newInstance(new Object[] { display }); } catch (Exception ex) { WorkbenchPlugin.log(StatusUtil.newStatus(IStatus.WARNING, "Could not start styling support.", //$NON-NLS-1$ ex)); } } // RAP [rh] workaround for bug #249630 // (IRunnableWithProgress in WorkbenchAdvisor does not show dialog) // // ModalContext should not spin the event loop (there is no UI yet to // // block) // ModalContext.setAllowReadAndDispatch(false); // if the -debug command line argument is used and the event loop is // being // run while starting the Workbench, log a warning. if (WorkbenchPlugin.getDefault().isDebugging()) { display.asyncExec(new Runnable() { public void run() { if (isStarting()) { WorkbenchPlugin .log(StatusUtil .newStatus( IStatus.WARNING, "Event loop should not be run while the Workbench is starting.", //$NON-NLS-1$ new RuntimeException())); } } }); } // RAP [bm]: not used // Listener closeListener = new Listener() { // public void handleEvent(Event event) { // event.doit = close(); // } // }; // RAPEND: [bm] // Initialize an exception handler. Window.IExceptionHandler handler = ExceptionHandler.getInstance(); try { // react to display close event by closing workbench nicely // RAP [bm]: Display#addListener // display.addListener(SWT.Close, closeListener); // install backstop to catch exceptions thrown out of event loop Window.setExceptionHandler(handler); final boolean [] initOK = new boolean[1]; // RAP [bm]: no splash // if (getSplash() != null) { // // final boolean[] initDone = new boolean[]{false}; // Thread initThread = new Thread() { // /* (non-Javadoc) // * @see java.lang.Thread#run() // */ // public void run() { // try { // //declare us to be a startup thread so that our syncs will be executed // UISynchronizer.startupThread.set(Boolean.TRUE); // initOK[0] = Workbench.this.init(); // } finally { // initDone[0] = true; // display.wake(); // } // }}; // initThread.start(); // while (true) { // if (!display.readAndDispatch()) { // if (initDone[0]) // break; // display.sleep(); // } // // } // } // else { // RAPEND: [bm] // initialize workbench and restore or open one window initOK[0] = init(); // } // drop the splash screen now that a workbench window is up Platform.endSplash(); // let the advisor run its start up code if (initOK[0]) { advisor.postStartup(); // may trigger a close/restart } if (initOK[0] && runEventLoop) { workbenchService = WorkbenchPlugin.getDefault() .getBundleContext().registerService( IWorkbench.class.getName(), this, null); // start eager plug-ins startPlugins(); addStartupRegistryListener(); // WWinPluginAction.refreshActionList(); display.asyncExec(new Runnable() { public void run() { UIStats.end(UIStats.START_WORKBENCH, this, "Workbench"); //$NON-NLS-1$ UIStats.startupComplete(); } }); getWorkbenchTestable().init(display, this); // allow ModalContext to spin the event loop ModalContext.setAllowReadAndDispatch(true); isStarting = false; if (synchronizer != null) synchronizer.started(); // the event loop runEventLoop(handler, display); } } catch (final Exception e) { if (!display.isDisposed()) { handler.handleException(e); } else { String msg = "Exception in Workbench.runUI after display was disposed"; //$NON-NLS-1$ WorkbenchPlugin.log(msg, new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH, 1, msg, e)); } } finally { // mandatory clean up // The runEventLoop flag may not have been cleared if an exception // occurred // Needs to be false to ensure PlatformUI.isWorkbenchRunning() // returns false. runEventLoop = false; // RAP [bm]: Display#removeListener // if (!display.isDisposed()) { // display.removeListener(SWT.Close, closeListener); // } // RAPEND: [bm] } // restart or exit based on returnCode return returnCode; } /* * Runs an event loop for the workbench. */ private void runEventLoop(Window.IExceptionHandler handler, Display display) { runEventLoop = true; while (runEventLoop) { try { if (!display.readAndDispatch()) { getAdvisor().eventLoopIdle(display); } } catch (Throwable t) { handler.handleException(t); // In case Display was closed under us if (display.isDisposed()) runEventLoop = false; } } } /* * Saves the current state of the workbench so it can be restored later on */ private IStatus saveState(IMemento memento) { MultiStatus result = new MultiStatus(PlatformUI.PLUGIN_ID, IStatus.OK, WorkbenchMessages.get().Workbench_problemsSaving, null); // Save the version number. memento.putString(IWorkbenchConstants.TAG_VERSION, VERSION_STRING[1]); // Save how many plug-ins were loaded while restoring the workbench if (progressCount != -1) { memento.putInteger(IWorkbenchConstants.TAG_PROGRESS_COUNT, progressCount); } // Save the advisor state. IMemento advisorState = memento .createChild(IWorkbenchConstants.TAG_WORKBENCH_ADVISOR); result.add(getAdvisor().saveState(advisorState)); // Save the workbench windows. IWorkbenchWindow[] windows = getWorkbenchWindows(); for (int nX = 0; nX < windows.length; nX++) { WorkbenchWindow window = (WorkbenchWindow) windows[nX]; IMemento childMem = memento .createChild(IWorkbenchConstants.TAG_WINDOW); result.merge(window.saveState(childMem)); } result.add(getEditorHistory().saveState( memento.createChild(IWorkbenchConstants.TAG_MRU_LIST))); return result; } /* * Save the workbench UI in a persistence file. */ private boolean saveMementoToFile(XMLMemento memento) { // Save it to a file. // XXX: nobody currently checks the return value of this method. // RAP [fappel]: need solution that allows cluster support // File stateFile = getWorkbenchStateFile(); // if (stateFile == null) { // return false; // } // try { // FileOutputStream stream = new FileOutputStream(stateFile); // OutputStreamWriter writer = new OutputStreamWriter(stream, "utf-8"); //$NON-NLS-1$ // memento.save(writer); // writer.close(); // } catch (IOException e) { // stateFile.delete(); // MessageDialog.openError((Shell) null, // WorkbenchMessages.get().SavingProblem, // WorkbenchMessages.get().ProblemSavingState); // return false; // } boolean result = false; try { StringWriter writer = new StringWriter(); memento.save( writer ); SettingStore settingStore = RWT.getSettingStore(); settingStore.setAttribute( KEY_WORKBENCH_STATE, writer.toString() ); result = true; } catch( final IOException ioe ) { WorkbenchPlugin.log( WorkbenchMessages.get().ProblemSavingState, ioe ); } return result; } /* * (non-Javadoc) Method declared on IWorkbench. */ public IWorkbenchPage showPerspective(String perspectiveId, IWorkbenchWindow window) throws WorkbenchException { Assert.isNotNull(perspectiveId); // If the specified window has the requested perspective open, then the // window // is given focus and the perspective is shown. The page's input is // ignored. WorkbenchWindow win = (WorkbenchWindow) window; if (win != null) { WorkbenchPage page = win.getActiveWorkbenchPage(); if (page != null) { IPerspectiveDescriptor perspectives[] = page .getOpenPerspectives(); for (int i = 0; i < perspectives.length; i++) { IPerspectiveDescriptor persp = perspectives[i]; if (perspectiveId.equals(persp.getId())) { win.makeVisible(); page.setPerspective(persp); return page; } } } } // If another window that has the workspace root as input and the // requested // perpective open and active, then the window is given focus. IAdaptable input = getDefaultPageInput(); IWorkbenchWindow[] windows = getWorkbenchWindows(); for (int i = 0; i < windows.length; i++) { win = (WorkbenchWindow) windows[i]; if (window != win) { WorkbenchPage page = win.getActiveWorkbenchPage(); if (page != null) { boolean inputSame = false; if (input == null) { inputSame = (page.getInput() == null); } else { inputSame = input.equals(page.getInput()); } if (inputSame) { Perspective persp = page.getActivePerspective(); if (persp != null) { IPerspectiveDescriptor desc = persp.getDesc(); if (desc != null) { if (perspectiveId.equals(desc.getId())) { Shell shell = win.getShell(); shell.open(); if (shell.getMinimized()) { shell.setMinimized(false); } return page; } } } } } } } // Otherwise the requested perspective is opened and shown in the // specified // window or in a new window depending on the current user preference // for opening // perspectives, and that window is given focus. win = (WorkbenchWindow) window; if (win != null) { IPreferenceStore store = WorkbenchPlugin.getDefault() .getPreferenceStore(); int mode = store.getInt(IPreferenceConstants.OPEN_PERSP_MODE); IWorkbenchPage page = win.getActiveWorkbenchPage(); IPerspectiveDescriptor persp = null; if (page != null) { persp = page.getPerspective(); } // Only open a new window if user preference is set and the window // has an active perspective. if (IPreferenceConstants.OPM_NEW_WINDOW == mode && persp != null) { IWorkbenchWindow newWindow = openWorkbenchWindow(perspectiveId, input); return newWindow.getActivePage(); } IPerspectiveDescriptor desc = getPerspectiveRegistry() .findPerspectiveWithId(perspectiveId); if (desc == null) { throw new WorkbenchException( NLS .bind( WorkbenchMessages.get().WorkbenchPage_ErrorCreatingPerspective, perspectiveId)); } win.getShell().open(); if (page == null) { page = win.openPage(perspectiveId, input); } else { page.setPerspective(desc); } return page; } // Just throw an exception.... throw new WorkbenchException(NLS .bind(WorkbenchMessages.get().Workbench_showPerspectiveError, perspectiveId)); } /* * (non-Javadoc) Method declared on IWorkbench. */ public IWorkbenchPage showPerspective(String perspectiveId, IWorkbenchWindow window, IAdaptable input) throws WorkbenchException { Assert.isNotNull(perspectiveId); // If the specified window has the requested perspective open and the // same requested // input, then the window is given focus and the perspective is shown. boolean inputSameAsWindow = false; WorkbenchWindow win = (WorkbenchWindow) window; if (win != null) { WorkbenchPage page = win.getActiveWorkbenchPage(); if (page != null) { boolean inputSame = false; if (input == null) { inputSame = (page.getInput() == null); } else { inputSame = input.equals(page.getInput()); } if (inputSame) { inputSameAsWindow = true; IPerspectiveDescriptor perspectives[] = page .getOpenPerspectives(); for (int i = 0; i < perspectives.length; i++) { IPerspectiveDescriptor persp = perspectives[i]; if (perspectiveId.equals(persp.getId())) { win.makeVisible(); page.setPerspective(persp); return page; } } } } } // If another window has the requested input and the requested // perpective open and active, then that window is given focus. IWorkbenchWindow[] windows = getWorkbenchWindows(); for (int i = 0; i < windows.length; i++) { win = (WorkbenchWindow) windows[i]; if (window != win) { WorkbenchPage page = win.getActiveWorkbenchPage(); if (page != null) { boolean inputSame = false; if (input == null) { inputSame = (page.getInput() == null); } else { inputSame = input.equals(page.getInput()); } if (inputSame) { Perspective persp = page.getActivePerspective(); if (persp != null) { IPerspectiveDescriptor desc = persp.getDesc(); if (desc != null) { if (perspectiveId.equals(desc.getId())) { win.getShell().open(); return page; } } } } } } } // If the specified window has the same requested input but not the // requested // perspective, then the window is given focus and the perspective is // opened and shown // on condition that the user preference is not to open perspectives in // a new window. win = (WorkbenchWindow) window; if (inputSameAsWindow && win != null) { IPreferenceStore store = WorkbenchPlugin.getDefault() .getPreferenceStore(); int mode = store.getInt(IPreferenceConstants.OPEN_PERSP_MODE); if (IPreferenceConstants.OPM_NEW_WINDOW != mode) { IWorkbenchPage page = win.getActiveWorkbenchPage(); IPerspectiveDescriptor desc = getPerspectiveRegistry() .findPerspectiveWithId(perspectiveId); if (desc == null) { throw new WorkbenchException( NLS .bind( WorkbenchMessages.get().WorkbenchPage_ErrorCreatingPerspective, perspectiveId)); } win.getShell().open(); if (page == null) { page = win.openPage(perspectiveId, input); } else { page.setPerspective(desc); } return page; } } // If the specified window has no active perspective, then open the // requested perspective and show the specified window. if (win != null) { IWorkbenchPage page = win.getActiveWorkbenchPage(); IPerspectiveDescriptor persp = null; if (page != null) { persp = page.getPerspective(); } if (persp == null) { IPerspectiveDescriptor desc = getPerspectiveRegistry() .findPerspectiveWithId(perspectiveId); if (desc == null) { throw new WorkbenchException( NLS .bind( WorkbenchMessages.get().WorkbenchPage_ErrorCreatingPerspective, perspectiveId)); } win.getShell().open(); if (page == null) { page = win.openPage(perspectiveId, input); } else { page.setPerspective(desc); } return page; } } // Otherwise the requested perspective is opened and shown in a new // window, and the // window is given focus. IWorkbenchWindow newWindow = openWorkbenchWindow(perspectiveId, input); return newWindow.getActivePage(); } /* * Shuts down the application. */ private void shutdown() { // shutdown application-specific portions first try { advisor.postShutdown(); } catch (Exception ex) { StatusManager.getManager().handle( StatusUtil.newStatus(WorkbenchPlugin.PI_WORKBENCH, "Exceptions during shutdown", ex)); //$NON-NLS-1$ } // notify regular workbench clients of shutdown, and clear the list when // done firePostShutdown(); workbenchListeners.clear(); cancelEarlyStartup(); if (workbenchService != null) workbenchService.unregister(); // for dynamic UI Platform.getExtensionRegistry().removeRegistryChangeListener( extensionEventHandler); Platform.getExtensionRegistry().removeRegistryChangeListener( startupRegistryListener); ((GrabFocus) Tweaklets.get(GrabFocus.KEY)).dispose(); // Bring down all of the services. serviceLocator.dispose(); workbenchActivitySupport.dispose(); WorkbenchHelpSystem.disposeIfNecessary(); // shutdown the rest of the workbench WorkbenchColors.shutdown(); activityHelper.shutdown(); uninitializeImages(); if (WorkbenchPlugin.getDefault() != null) { WorkbenchPlugin.getDefault().reset(); } WorkbenchThemeManager.getInstance().dispose(); PropertyPageContributorManager.getManager().dispose(); ObjectActionContributorManager.getManager().dispose(); if (tracker != null) { tracker.close(); } } /** * Cancels the early startup job, if it's still running. */ private void cancelEarlyStartup() { Job.getJobManager().cancel(EARLY_STARTUP_FAMILY); // We do not currently wait for any plug-in currently being started to // complete // (e.g. by doing a join on EARLY_STARTUP_FAMILY), since they may do a // syncExec, // which would hang. See bug 94537 for rationale. } /* * (non-Javadoc) Method declared on IWorkbench. */ public IDecoratorManager getDecoratorManager() { return WorkbenchPlugin.getDefault().getDecoratorManager(); } /* * Returns the workbench window which was last known being the active one, * or <code> null </code> . */ private WorkbenchWindow getActivatedWindow() { if (activatedWindow != null) { Shell shell = activatedWindow.getShell(); if (shell != null && !shell.isDisposed()) { return activatedWindow; } } return null; } /* * Sets the workbench window which was last known being the active one, or * <code> null </code> . */ /* package */ void setActivatedWindow(WorkbenchWindow window) { activatedWindow = window; } /** * Returns the unique object that applications use to configure the * workbench. * <p> * IMPORTANT This method is declared package-private to prevent regular * plug-ins from downcasting IWorkbench to Workbench and getting hold of the * workbench configurer that would allow them to tamper with the workbench. * The workbench configurer is available only to the application. * </p> */ /* package */ WorkbenchConfigurer getWorkbenchConfigurer() { if (workbenchConfigurer == null) { workbenchConfigurer = new WorkbenchConfigurer(); } return workbenchConfigurer; } /** * Returns the workbench advisor that created this workbench. * <p> * IMPORTANT This method is declared package-private to prevent regular * plug-ins from downcasting IWorkbench to Workbench and getting hold of the * workbench advisor that would allow them to tamper with the workbench. The * workbench advisor is internal to the application. * </p> */ /* package */ WorkbenchAdvisor getAdvisor() { return advisor; } /* * (non-Javadoc) Method declared on IWorkbench. */ public Display getDisplay() { return display; } /** * Returns the default perspective id, which may be <code>null</code>. * * @return the default perspective id, or <code>null</code> */ public String getDefaultPerspectiveId() { return getAdvisor().getInitialWindowPerspectiveId(); } /** * Returns the default workbench window page input. * * @return the default window page input or <code>null</code> if none */ public IAdaptable getDefaultPageInput() { return getAdvisor().getDefaultPageInput(); } /** * Returns the id of the preference page that should be presented most * prominently. * * @return the id of the preference page, or <code>null</code> if none */ public String getMainPreferencePageId() { String id = getAdvisor().getMainPreferencePageId(); return id; } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench */ public IElementFactory getElementFactory(String factoryId) { Assert.isNotNull(factoryId); return WorkbenchPlugin.getDefault().getElementFactory(factoryId); } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#getProgressService() */ public IProgressService getProgressService() { return ProgressManager.getInstance(); } private WorkbenchActivitySupport workbenchActivitySupport; // RAP [rh] unused code: getCommandSupport is disabled // private WorkbenchCommandSupport workbenchCommandSupport; private WorkbenchContextSupport workbenchContextSupport; /** * The single instance of the binding manager used by the workbench. This is * initialized in <code>Workbench.init(Display)</code> and then never * changed. This value will only be <code>null</code> if the * initialization call has not yet completed. */ private BindingManager bindingManager; /** * The single instance of the command manager used by the workbench. This is * initialized in <code>Workbench.init(Display)</code> and then never * changed. This value will only be <code>null</code> if the * initialization call has not yet completed. */ private CommandManager commandManager; /** * The single instance of the context manager used by the workbench. This is * initialized in <code>Workbench.init(Display)</code> and then never * changed. This value will only be <code>null</code> if the * initialization call has not yet completed. */ private ContextManager contextManager; public IWorkbenchActivitySupport getActivitySupport() { return workbenchActivitySupport; } // RAP [rh] useless API: IWorkbenchCommandSupport heavily relies on keys // public IWorkbenchCommandSupport getCommandSupport() { // return workbenchCommandSupport; // } public IWorkbenchContextSupport getContextSupport() { return workbenchContextSupport; } /** * This method should not be called outside the framework. * * @return The context manager. */ public ContextManager getContextManager() { return contextManager; } private final IWindowListener windowListener = new IWindowListener() { public void windowActivated(IWorkbenchWindow window) { updateActiveWorkbenchWindowMenuManager(true); } public void windowClosed(IWorkbenchWindow window) { updateActiveWorkbenchWindowMenuManager(true); } public void windowDeactivated(IWorkbenchWindow window) { updateActiveWorkbenchWindowMenuManager(true); } public void windowOpened(IWorkbenchWindow window) { updateActiveWorkbenchWindowMenuManager(true); } }; private final IBindingManagerListener bindingManagerListener = new IBindingManagerListener() { public void bindingManagerChanged( BindingManagerEvent bindingManagerEvent) { if (bindingManagerEvent.isActiveBindingsChanged()) { updateActiveWorkbenchWindowMenuManager(true); } } }; /** * The source provider that tracks the activation of action sets within the * workbench. This source provider is <code>null</code> until * {@link #initializeDefaultServices()} is called. */ private ActionSetSourceProvider actionSetSourceProvider; private WorkbenchWindow activeWorkbenchWindow = null; private void updateActiveWorkbenchWindowMenuManager(boolean textOnly) { if (activeWorkbenchWindow != null) { activeWorkbenchWindow .removeActionSetsListener(actionSetSourceProvider); activeWorkbenchWindow = null; } boolean actionSetsUpdated = false; final IWorkbenchWindow workbenchWindow = getActiveWorkbenchWindow(); if (workbenchWindow instanceof WorkbenchWindow) { activeWorkbenchWindow = (WorkbenchWindow) workbenchWindow; if (activeWorkbenchWindow.isClosing()) { return; } // Update the action sets. final Shell windowShell = activeWorkbenchWindow.getShell(); final Shell activeShell = getDisplay().getActiveShell(); final IContextService service = (IContextService) getService(IContextService.class); if (Util.equals(windowShell, activeShell) || service.getShellType(activeShell) == IContextService.TYPE_WINDOW) { activeWorkbenchWindow .addActionSetsListener(actionSetSourceProvider); final WorkbenchPage page = activeWorkbenchWindow .getActiveWorkbenchPage(); final IActionSetDescriptor[] newActionSets; if (page != null) { newActionSets = page.getActionSets(); final ActionSetsEvent event = new ActionSetsEvent( newActionSets); actionSetSourceProvider.actionSetsChanged(event); actionSetsUpdated = true; } } final MenuManager menuManager = activeWorkbenchWindow .getMenuManager(); if (textOnly) { menuManager.update(IAction.TEXT); } else { menuManager.update(true); } } if (!actionSetsUpdated) { final ActionSetsEvent event = new ActionSetsEvent(null); actionSetSourceProvider.actionSetsChanged(event); } } private ActivityPersistanceHelper activityHelper; /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#getIntroManager() */ public IIntroManager getIntroManager() { return getWorkbenchIntroManager(); } /** * @return the workbench intro manager */ /* package */WorkbenchIntroManager getWorkbenchIntroManager() { if (introManager == null) { introManager = new WorkbenchIntroManager(this); } return introManager; } private WorkbenchIntroManager introManager; /** * @return the intro extension for this workbench. */ public IntroDescriptor getIntroDescriptor() { return introDescriptor; } /** * This method exists as a test hook. This method should <strong>NEVER</strong> * be called by clients. * * @param descriptor * The intro descriptor to use. */ public void setIntroDescriptor(IntroDescriptor descriptor) { if (getIntroManager().getIntro() != null) { getIntroManager().closeIntro(getIntroManager().getIntro()); } introDescriptor = descriptor; } /** * The descriptor for the intro extension that is valid for this workspace, * <code>null</code> if none. */ private IntroDescriptor introDescriptor; private IExtensionTracker tracker; private IRegistryChangeListener startupRegistryListener = new IRegistryChangeListener() { /* * (non-Javadoc) * * @see org.eclipse.core.runtime.IRegistryChangeListener#registryChanged(org.eclipse.core.runtime.IRegistryChangeEvent) */ public void registryChanged(IRegistryChangeEvent event) { // RAP [bm]: namespace final IExtensionDelta[] deltas = event.getExtensionDeltas( PlatformUI.PLUGIN_EXTENSION_NAME_SPACE, IWorkbenchRegistryConstants.PL_STARTUP); if (deltas.length == 0) { return; } final String disabledPlugins = PrefUtil .getInternalPreferenceStore() .getString( IPreferenceConstants.PLUGINS_NOT_ACTIVATED_ON_STARTUP); for (int i = 0; i < deltas.length; i++) { IExtension extension = deltas[i].getExtension(); if (deltas[i].getKind() == IExtensionDelta.REMOVED) { continue; } // if the plugin is not in the set of disabled plugins, // then // execute the code to start it if (disabledPlugins.indexOf(extension.getNamespace()) == -1) { SafeRunner.run(new EarlyStartupRunnable(extension)); } } } }; private String factoryID; /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#getThemeManager() */ public IThemeManager getThemeManager() { return WorkbenchThemeManager.getInstance(); } /** * Returns <code>true</code> if the workbench is running, * <code>false</code> if it has been terminated. * * @return <code>true</code> if the workbench is running, * <code>false</code> if it has been terminated. */ public boolean isRunning() { return runEventLoop; } /** * Return the presentation ID specified by the preference or the default ID * if undefined. * * @return the presentation ID * @see IWorkbenchPreferenceConstants#PRESENTATION_FACTORY_ID */ public String getPresentationId() { if (factoryID != null) { return factoryID; } factoryID = PrefUtil.getAPIPreferenceStore().getString( IWorkbenchPreferenceConstants.PRESENTATION_FACTORY_ID); // Workaround for bug 58975 - New preference mechanism does not properly // initialize defaults // Ensure that the UI plugin has started too. if (factoryID == null || factoryID.equals("")) { //$NON-NLS-1$ factoryID = IWorkbenchConstants.DEFAULT_PRESENTATION_ID; } return factoryID; } /** * <p> * Indicates the start of a large update within the workbench. This is used * to disable CPU-intensive, change-sensitive services that were temporarily * disabled in the midst of large changes. This method should always be * called in tandem with <code>largeUpdateEnd</code>, and the event loop * should not be allowed to spin before that method is called. * </p> * <p> * Important: always use with <code>largeUpdateEnd</code>! * </p> */ public final void largeUpdateStart() { if (largeUpdates++ == 0) { // TODO Consider whether these lines still need to be here. // workbenchCommandSupport.setProcessing(false); // workbenchContextSupport.setProcessing(false); final IWorkbenchWindow[] windows = getWorkbenchWindows(); for (int i = 0; i < windows.length; i++) { IWorkbenchWindow window = windows[i]; if (window instanceof WorkbenchWindow) { ((WorkbenchWindow) window).largeUpdateStart(); } } } } /** * <p> * Indicates the end of a large update within the workbench. This is used to * re-enable services that were temporarily disabled in the midst of large * changes. This method should always be called in tandem with * <code>largeUpdateStart</code>, and the event loop should not be * allowed to spin before this method is called. * </p> * <p> * Important: always protect this call by using <code>finally</code>! * </p> */ public final void largeUpdateEnd() { if (--largeUpdates == 0) { // TODO Consider whether these lines still need to be here. // workbenchCommandSupport.setProcessing(true); // workbenchContextSupport.setProcessing(true); // Perform window-specific blocking. final IWorkbenchWindow[] windows = getWorkbenchWindows(); for (int i = 0; i < windows.length; i++) { IWorkbenchWindow window = windows[i]; if (window instanceof WorkbenchWindow) { ((WorkbenchWindow) window).largeUpdateEnd(); } } } } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#getExtensionTracker() */ public IExtensionTracker getExtensionTracker() { if (tracker == null) { tracker = new UIExtensionTracker(getDisplay()); } return tracker; } /** * Adds the listener that handles startup plugins */ private void addStartupRegistryListener() { IExtensionRegistry registry = Platform.getExtensionRegistry(); registry.addRegistryChangeListener(startupRegistryListener); } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#getHelpSystem() */ public IWorkbenchHelpSystem getHelpSystem() { return WorkbenchHelpSystem.getInstance(); } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#getHelpSystem() */ public IWorkbenchBrowserSupport getBrowserSupport() { return WorkbenchBrowserSupport.getInstance(); } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#getViewRegistry() */ public IViewRegistry getViewRegistry() { return WorkbenchPlugin.getDefault().getViewRegistry(); } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#getNewWizardRegistry() */ public IWizardRegistry getNewWizardRegistry() { return WorkbenchPlugin.getDefault().getNewWizardRegistry(); } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#getImportWizardRegistry() */ public IWizardRegistry getImportWizardRegistry() { return WorkbenchPlugin.getDefault().getImportWizardRegistry(); } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#getExportWizardRegistry() */ public IWizardRegistry getExportWizardRegistry() { return WorkbenchPlugin.getDefault().getExportWizardRegistry(); } public final Object getAdapter(final Class key) { return serviceLocator.getService(key); } private void doRestoreState(final IMemento memento, final MultiStatus status) { IMemento childMem; try { UIStats.start(UIStats.RESTORE_WORKBENCH, "MRUList"); //$NON-NLS-1$ IMemento mruMemento = memento .getChild(IWorkbenchConstants.TAG_MRU_LIST); if (mruMemento != null) { status.add(getEditorHistory().restoreState(mruMemento)); } } finally { UIStats.end(UIStats.RESTORE_WORKBENCH, this, "MRUList"); //$NON-NLS-1$ } // Restore advisor state. IMemento advisorState = memento .getChild(IWorkbenchConstants.TAG_WORKBENCH_ADVISOR); if (advisorState != null) { status.add(getAdvisor().restoreState(advisorState)); } // Get the child windows. IMemento[] children = memento .getChildren(IWorkbenchConstants.TAG_WINDOW); createdWindows = new WorkbenchWindow[children.length]; // Read the workbench windows. for (int i = 0; i < children.length; i++) { childMem = children[i]; final WorkbenchWindow [] newWindow = new WorkbenchWindow[1]; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() { newWindow[0] = newWorkbenchWindow(); newWindow[0].create(); }}); createdWindows[i] = newWindow[0]; // allow the application to specify an initial perspective to open // @issue temporary workaround for ignoring initial perspective // String initialPerspectiveId = // getAdvisor().getInitialWindowPerspectiveId(); // if (initialPerspectiveId != null) { // IPerspectiveDescriptor desc = // getPerspectiveRegistry().findPerspectiveWithId(initialPerspectiveId); // result.merge(newWindow.restoreState(childMem, desc)); // } // add the window so that any work done in newWindow.restoreState // that relies on Workbench methods has windows to work with windowManager.add(newWindow[0]); // now that we've added it to the window manager we need to listen // for any exception that might hose us before we get a chance to // open it. If one occurs, remove the new window from the manager. // Assume that the new window is a phantom for now boolean restored = false; try { status.merge(newWindow[0].restoreState(childMem, null)); try { newWindow[0].fireWindowRestored(); } catch (WorkbenchException e) { status.add(e.getStatus()); } // everything worked so far, don't close now restored = true; } finally { if (!restored) { // null the window in newWindowHolder so that it won't be // opened later on createdWindows[i] = null; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable { newWindow[0].close(); }}); } } } } private void openWindowsAfterRestore() { if (createdWindows == null) { return; } // now open the windows (except the ones that were nulled because we // closed them above) for (int i = 0; i < createdWindows.length; i++) { if (createdWindows[i] != null) { final WorkbenchWindow myWindow = createdWindows[i]; StartupThreading.runWithoutExceptions(new StartupRunnable() { public void runWithException() throws Throwable { boolean opened = false; try { myWindow.open(); opened = true; } finally { if (!opened) { myWindow.close(); } } }}); } } createdWindows = null; } /* * (non-Javadoc) * * @see org.eclipse.ui.services.IServiceLocator#getService(java.lang.Object) */ public final Object getService(final Class key) { return serviceLocator.getService(key); } /* * (non-Javadoc) * * @see org.eclipse.ui.services.IServiceLocator#hasService(java.lang.Object) */ public final boolean hasService(final Class key) { return serviceLocator.hasService(key); } /** * Registers a service with this locator. If there is an existing service * matching the same <code>api</code> and it implements * {@link IDisposable}, it will be disposed. * * @param api * This is the interface that the service implements. Must not be * <code>null</code>. * @param service * The service to register. This must be some implementation of * <code>api</code>. This value must not be <code>null</code>. */ public final void registerService(final Class api, final Object service) { serviceLocator.registerService(api, service); } /** * The source provider that tracks which context menus (i.e., menus with * target identifiers) are now showing. This value is <code>null</code> * until {@link #initializeDefaultServices()} is called. */ private MenuSourceProvider menuSourceProvider; /** * Adds the ids of a menu that is now showing to the menu source provider. * This is used for legacy action-based handlers which need to become active * only for the duration of a menu being visible. * * @param menuIds * The identifiers of the menu that is now showing; must not be * <code>null</code>. * @param localSelection * @param localEditorInput */ public final void addShowingMenus(final Set menuIds, final ISelection localSelection, final ISelection localEditorInput) { menuSourceProvider.addShowingMenus(menuIds, localSelection, localEditorInput); } /** * Removes the ids of a menu that is now hidden from the menu source * provider. This is used for legacy action-based handlers which need to * become active only for the duration of a menu being visible. * * @param menuIds * The identifiers of the menu that is now hidden; must not be * <code>null</code>. * @param localSelection * @param localEditorInput */ public final void removeShowingMenus(final Set menuIds, final ISelection localSelection, final ISelection localEditorInput) { menuSourceProvider.removeShowingMenus(menuIds, localSelection, localEditorInput); } /* (non-Javadoc) * @see org.eclipse.ui.IWorkbench#saveAll(org.eclipse.jface.window.IShellProvider, org.eclipse.jface.operation.IRunnableContext, org.eclipse.ui.ISaveableFilter, boolean) */ public boolean saveAll(IShellProvider shellProvider, IRunnableContext runnableContext, ISaveableFilter filter, boolean confirm) { SaveablesList saveablesList = (SaveablesList) PlatformUI.getWorkbench() .getService(ISaveablesLifecycleListener.class); Saveable[] saveables = saveablesList.getOpenModels(); List toSave = getFilteredSaveables(filter, saveables); if (toSave.isEmpty()) return true; if (!confirm) { return !saveablesList.saveModels(toSave, shellProvider, runnableContext); } // We must negate the result since false is cancel saveAll return !saveablesList.promptForSaving(toSave, shellProvider, runnableContext, true, false); } /* * Apply the given filter to the list of saveables */ private List getFilteredSaveables(ISaveableFilter filter, Saveable[] saveables) { List toSave = new ArrayList(); if (filter == null) { for (int i = 0; i < saveables.length; i++) { Saveable saveable = saveables[i]; if (saveable.isDirty()) toSave.add(saveable); } } else { SaveablesList saveablesList = (SaveablesList)getService(ISaveablesLifecycleListener.class); for (int i = 0; i < saveables.length; i++) { Saveable saveable = saveables[i]; if (saveable.isDirty()) { IWorkbenchPart[] parts = saveablesList.getPartsForSaveable(saveable); if (matchesFilter(filter, saveable, parts)) toSave.add(saveable); } } } return toSave; } /* * Test whether the given filter matches the saveable */ private boolean matchesFilter(ISaveableFilter filter, Saveable saveable, IWorkbenchPart[] parts) { return filter == null || filter.select(saveable, parts); } /* * (non-Javadoc) * * @see org.eclipse.ui.IWorkbench#getModalDialogShellProvider() */ public IShellProvider getModalDialogShellProvider() { return new IShellProvider() { public Shell getShell() { return ProgressManagerUtil.getDefaultParent(); } }; } }